#pragma  once

namespace MomogenkyouSystem	{

class InputSystem
{
protected:
	static	BYTE						KeyboardKeys[256];			//	Keys states of current frame
	static	BYTE						PrevKeyboardKeys[256];		//	Keys states of previous frame
	static	DIMOUSESTATE2				MouseState;					//	Mouse state of current frame
	static	DIMOUSESTATE2				PrevMouseState;				//	Mouse state of previous frame

	static	POINT						MousePosition;				//	Mouse Position of current frame
	static	POINT						PrevMousePosition;			//	Mouse position of previous frame
	
	static	LPDIRECTINPUT				DeviceManager;				//	Direct Input's Devicemanager
	static	LPDIRECTINPUTDEVICE			KeyboardDevice;				//	Keyboard Device
	static	LPDIRECTINPUTDEVICE			MouseDevice;				//	Mouse Device
public:
	//	Initialize the input system
	//	@param	param_WindowHandle		HWND of created window
	//	@param	param_WindowInstance	HINSTANCE of created window
	static	bool						Initialize(	const HWND		&	param_WindowHandle,
													const HINSTANCE &	param_WindowInstance);

	//	Shutsdown the input system
	static	bool						Shutdown();

	static	void						Update(const float & fInterval);

	//	Refer to DIK keycodes instead of VK keycodes
	//	Mouse Button are defined at Term.h

	static	__inline	bool			KeyDown(const size_t & Key)				{	return (KeyboardKeys[Key] & 0x80)? true : false;	}
	static	__inline	bool			KeyUp(const size_t & Key)				{	return (KeyboardKeys[Key] & 0x80)? false : true;	}

	static	__inline	bool			KeyPressed(const size_t & Key)			{	return (KeyboardKeys[Key] & 0x80) && !(PrevKeyboardKeys[Key] & 0x80);	}
	static	__inline	bool			KeyReleased(const size_t & Key)			{	return !(KeyboardKeys[Key] & 0x80) && (PrevKeyboardKeys[Key] & 0x80);	}

	static	__inline	bool			MouseDown(const size_t & Button)		{	return	(MouseState.rgbButtons[Button] & 0x80)? true : false;	}
	static	__inline	bool			MouseUp(const size_t & Button)			{	return	(MouseState.rgbButtons[Button] & 0x80)? false: true;	}

	static	__inline	bool			MousePressed(const size_t & Button)		{	return	(MouseState.rgbButtons[Button] & 0x80) && !(MouseState.rgbButtons[Button] & 0x80);	}
	static	__inline	bool			MouseReleased(const size_t & Button)	{	return	!(MouseState.rgbButtons[Button] & 0x80) && (MouseState.rgbButtons[Button] & 0x80);	}

	static	__inline	float			MouseMoveX()							{	return	static_cast<float>(MouseState.lX);	}
	static	__inline	float			MouseMoveY()							{	return	static_cast<float>(MouseState.lY);	}
	static	__inline	float			MouseWheelMove()						{	return	static_cast<float>(MouseState.lZ);	}

	static	__inline	POINT			MousePos()								{	return	MousePosition;		}
	static	__inline	POINT			MouseLastPos()							{	return	PrevMousePosition;	}
};


}